package game.johan.engine;
/*
Copyright (C) 2013 Johan Ceuppens

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/


import java.io.BufferedInputStream;
import java.io.FileInputStream;

import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.graphics.Bitmap;
import android.view.SurfaceView;
import android.content.Context;

//FIXME 2 singletons for _canvas & _canvasThreand & Holders
public class EngineBase extends SurfaceView implements SurfaceHolder.Callback
{
	private int _multicore = 2;//FIXME changes at runtime
	private GameObjectThread _drawthread;
	private GameObjectUpdateThread _updatethread;
	
	private GameThreadSingleCore _gamethreadsinglecore;
	
	private Canvas _canvas;
	private int _screenw;
	private int _screenh;
	private Surface _screensurface;
	private SurfaceList _surfacelist;
	private AIMachine _aimachine;
	
	public EngineBase(Context context, AttributeSet attributeset) {
		super(context, attributeset);
		
		this.getHolder().addCallback(this);
		this.setFocusable(true);
		
		_screenw = 320;
		_screenh = 200;
		_screensurface = new Surface(_screenw,_screenh);
		
		_surfacelist = new SurfaceList(this);
	
	}

	//FIXME not at runtime
	public void setToSingleCore() {
		_multicore = 1;
	}
	
	public void setToMultiCore() {
		_multicore = 1;
	}
	
@Override
  public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2,
          int arg3) {
	//stub
  }

  @Override
  public void surfaceCreated(SurfaceHolder arg0) {
	  
	  if (_multicore == 2) {
		  
	  /*
	   * async game event handler, with GameEvent instances for events
	   * This might be changed to multiple handlers for (multi-core) systems
	   */
      final GameObjectEventSource _draweventsource = new GameDrawEventSource(this);
      final GameEventHandler _draweventhandler = new GameDrawEventHandler();
      _draweventsource.addObserver(_draweventhandler);

      // starts the drawing event thread
      _drawthread = new GameObjectThread(this,_draweventsource);
      _drawthread.start();
      
      final GameObjectEventSource _updateeventsource = new GameDrawEventSource(this);
      final GameEventHandler _updateeventhandler = new GameDrawEventHandler();
      _updateeventsource.addObserver(_updateeventhandler);

      // starts the update event thread
      _updatethread = new GameObjectUpdateThread(this,_draweventsource);
      _updatethread.start();

	  } else {
		  
		  final GameEventSource _eventsource = new GameEventSource(this);
	      final GameEventHandler _eventhandler = new GameEventHandler();
	      _eventsource.addObserver(_eventhandler);

	      // starts the drawing event thread
	      _gamethreadsinglecore = new GameThreadSingleCore(this,_eventsource);
	      _gamethreadsinglecore.start();
		  
	  }
  }
  
  public void render(Canvas canvas) {
	  	_canvas = canvas;//FIXME ? screensurface
	  	lockCanvas1();
	  	_surfacelist.drawOn(_screensurface);
	  	_screensurface.render(this);
	  	unlockCanvas1();
  }

  public void update() {
	  _aimachine.update();
  }
  
  @Override
  public void surfaceDestroyed(SurfaceHolder arg0) {

	  if (_multicore == 2) {
	  
	  boolean retry = true;
	  _drawthread.setRunning(false);
	  _updatethread.setRunning(false);
	  while(retry) {
	  try {
		  _drawthread.join();
		  _updatethread.join();
		  retry = false;
	  	} catch (InterruptedException e) {
	    	System.out.println("Message "+e.getMessage());
	    	e.printStackTrace();
	  	}
	  }
	  } else {
		  boolean retry = true;
		  _gamethreadsinglecore.setRunning(false);
		  while(retry) {
		  try {
			  _gamethreadsinglecore.join();
			  retry = false;
		  	} catch (InterruptedException e) {
		    	System.out.println("Message "+e.getMessage());
		    	e.printStackTrace();
		  	}
		  }  
		  
		  
	  }
  }
  /** Called when the activity is first created. */
//  @Override
//  public void onCreate(Bundle savedInstanceState) {
//      super.onCreate(savedInstanceState);
//      setContentView(R.layout.main);
//      ImageView image = (ImageView) findViewById(R.id.test_image);
//      Bitmap bMap = BitmapFactory.decodeFile("/sdcard/test2.png");
//      image.setImageBitmap(bMap);
//  }
  
  protected Canvas lockCanvas1() {
	  _canvas = this.getHolder().lockCanvas(null);
	  return _canvas;
  }
  
  protected void drawOnCanvas1(Bitmap b) {
	  _canvas.drawBitmap(b, 0, 0, null);
  }
  
  protected void unlockCanvas1() {
	  this.getHolder().unlockCanvasAndPost(_canvas);
  }
  
  public void setscreenwh(int w, int h) {
	  _screenh = h;
	  _screenw = w;
  }
 }